package llama.view.panels;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import llama.core.IUser;
import llama.core.SearchResults;
import llama.core.SearchTerm;
import llama.ctrl.AddContactCtrl;
import llama.ctrl.ControllerFactory;
import llama.ctrl.NavigationCtrl;
import llama.ctrl.NavigationCtrl.NavigationType;
import llama.ctrl.SearchUserCtrl;

public class SearchUserPanel extends JPanel {
	private JTextField term;
	private JList list;
	private DefaultListModel listModel;
	private JButton addContact;
	private Map<IUser, Boolean> results;
	
	/**
	 * Create the panel.
	 */
	public SearchUserPanel() {
		setLayout(new BorderLayout(0, 0));
		
		JPanel panel = new JPanel();
		add(panel, BorderLayout.NORTH);
		panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		
		term = new JTextField();
		panel.add(term);
		term.setColumns(11);
		
		JButton search = new JButton("Search");
		panel.add(search);
		
		JScrollPane scrollPane = new JScrollPane();
		add(scrollPane, BorderLayout.CENTER);

		this.list = new JList();
		this.list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.list.setCellRenderer(new CellRenderer());
		scrollPane.setViewportView(this.list);
		listModel = new DefaultListModel();
		list.setModel(listModel);
		
		JPanel panel_1 = new JPanel();
		add(panel_1, BorderLayout.SOUTH);
		
		JButton back = new JButton("Back");		
		panel_1.add(back);
		
		this.addContact = new JButton("Add contact");
		panel_1.add(this.addContact);
		addContact.setEnabled(false);
		
		this.list.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				addContact.setEnabled(true);
				if(list.getSelectedIndex() < 0){
					addContact.setEnabled(false);
				}
				else if(list.getSelectedValue() instanceof IUser) {
					IUser user = (IUser)list.getSelectedValue();
					if(results.get(user)){ //Get the value of key, true if user is a contact
						list.clearSelection(); //Exist in the contact list, clear selection
					}
				} else {
					list.clearSelection();
				}
			}
		});
		
		search.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				search();
			}
		});
		
		term.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				search();
			}
		});
		
		this.addContact.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				AddContactCtrl add = (AddContactCtrl) ControllerFactory.getController(AddContactCtrl.class);
				IUser user = (IUser)list.getSelectedValue();
				
				results.put(user, true); //The user is now a contact
				add.setUser(user);
				add.execute();
				
				goBack();
			}
		});
		
		back.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				goBack();
			}
		});
	}
	
	private void search(){
		SearchUserCtrl search = (SearchUserCtrl) ControllerFactory.getController(SearchUserCtrl.class);
		search.setTerm(new SearchTerm(term.getText()));
		search.execute();
	}
	
	private void goBack(){
		NavigationCtrl nav = (NavigationCtrl) ControllerFactory.getController(NavigationCtrl.class);
		nav.setNavigation(NavigationType.BACK);
		nav.execute();
	}

	public void showSearchResuluts(SearchResults sr) {
		listModel = new DefaultListModel();
		results = sr.getResults();
		
		if (results != null && !results.isEmpty()) {
			Iterator<Map.Entry<IUser, Boolean>> it = results.entrySet().iterator();
			while(it.hasNext()){
				Map.Entry<IUser, Boolean> pair = it.next();
				listModel.addElement(pair.getKey());
			}
		}
		else {
			listModel.addElement("No contacts found.");
		}
		
		list.setModel(listModel);
		list.revalidate();
		list.repaint();
	}
	
	public void clear() {
		term.setText("");
		listModel.clear();
	}
	
	public class CellRenderer extends JLabel implements ListCellRenderer {
	    public CellRenderer() {
	        setOpaque(true);
	    }
	    
	    @Override
		public Component getListCellRendererComponent(final JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
	        setText(value.toString());
	        setForeground(Color.BLACK);
	        
	        if(isSelected){
	        	setBackground(new Color(9,205,218));
	        }
	        else {
	        	setBackground(Color.WHITE);
	        }
	        
	        if(value instanceof IUser && results.get(value)){ //Check if IUser is a contact
				setForeground(Color.GRAY);
	        }

	        return this;
	    }
	}
}
